/*
 * Project: push-center-service-impl
 * 
 * File Created at 2014-10-9
 * 
 * Copyright 2012 Greenline.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Greenline Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Greenline.com.
 */
package com.greenline.push.service.core.send;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.greenline.push.core.enums.Channels;
import com.greenline.push.core.enums.MsgSendType;
import com.greenline.push.core.enums.Tasks;
import com.greenline.push.service.core.item.AppPacket;
import com.greenline.push.service.core.item.Packet;
import com.greenline.push.service.core.send.base.AbstractSender;
import com.greenline.push.service.core.send.base.AppPacketHandler;
import com.greenline.push.service.core.tmpl.GroupAppCache;
import com.greenline.push.service.core.utils.Constants;
import com.greenline.push.service.core.utils.xmpp.XmppManager;

/**
 * XmppSender
 * 
 * @author shuai.zuo
 * 
 */
public class XmppSender extends AbstractSender {
    @Resource
    private GroupAppCache groupAppCache;
    @Resource
    private AppPacketHandler packetHandler;
    @Resource
    private XmppManager xmppManager;

    private final Logger logger = Constants.LOG_PROCESS;

    @Override
    public Channels supportChannel() {
        return Channels.xmpp;
    }

    @Override
    protected boolean doSend(Packet packet) {
        AppPacket appPacket = (AppPacket) packet;
        logger.info(String
                .format("{xmppsender收到数据}:准备发送***domainId:[%s].tempId:[%s].type:[%s],extparam-context:[%s-%s],source:[%s],retryId:[%s],thread:[%s]",
                        appPacket.getDomainId(), appPacket.getTemplateId(), appPacket.getType(), appPacket.getExtParam(),
                        appPacket.getContext(), appPacket.getSource(), appPacket.getDbRetryId(), Thread.currentThread().getName()));
        //
        boolean succ = false;
        if (MsgSendType.POINT.getType() == appPacket.getType()) {
            // succ = sendSms(mobile, context);
            succ = sendPoint(appPacket);
        } else if (MsgSendType.GROUP.getType() == appPacket.getType()) {
            sendGroup(appPacket);
        } else if (MsgSendType.UPLOAD.getType() == appPacket.getType() || MsgSendType.CONDITIONS.getType() == appPacket.getType()
                || MsgSendType.DOMAIN.getType() == appPacket.getType()) {
            // upload 或者 condition ,doamin类型 可以调用第三方按组发送
            this.sendList(appPacket);
        } else {
            // sendSmsGroup(appPacket);
            packetHandler.afterSendOperation(appPacket, succ, true);
        }

        // //测试代码
        // boolean succ = true;
        // try {
        // Thread.sleep(80l);
        // } catch (InterruptedException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // super.afterSendOperation(appPacket, succ);
        return succ;
    }

    private void sendList(AppPacket appPacket) {
        Long retryId = appPacket.getDbRetryId();

        List<String> sResult = getUserIdsByRetryId(retryId);
        if (sResult == null) {
            logger.error(String.format("{xmpp.sendList}发送失败,xmpp下没有取到用户.retryId:%s,context:%s", retryId, appPacket.getContext()));
            packetHandler.afterSendOperation(appPacket, false, true);
            return;
        }
        logger.debug(String.format("{xmpp***sendList}批量发送xmpp消息.uidlist:%s.contenxt:[%s],retryId:[%s]", sResult.toString(),
                appPacket.getContext(), appPacket.getDbRetryId()));
        // convert to p2p
        for (String userId : sResult) {
            appPacket.setDeviceToken(userId);
            sendPoint(appPacket);
        }
    }

    private boolean sendPoint(AppPacket appPacket) {
        String methodName = "{xmpp.sendPoint}";
        String uid = appPacket.getDeviceToken();
        String context = appPacket.getContext();
        logger.debug(String.format("%s开始推送:接收人[%s].内容:[%s]", methodName, uid, context));
        // do send
        boolean success = false;
        try {
            xmppManager.send(uid, context);
            success = true;
            packetHandler.afterSendOperation(appPacket, success);
            // log
            logger.info(String.format("%s发送完成:结果:[%s].domainId:[%s].tempId:[%s].extparam:[%s].接收人:[%s-%s].发送内容:[%s].retryId:[%s]",
                    methodName, success, appPacket.getDomainId(), appPacket.getTemplateId(), appPacket.getExtParam(),
                    appPacket.getRecvUserId(), appPacket.getDeviceToken(), appPacket.getContext(), appPacket.getDbRetryId()));
        } catch (Exception e) {
            e.printStackTrace();
            packetHandler.afterSendOperation(appPacket, success);
            logger.error(String.format("%s推送异常.接收人:[%s],内容:[%s],原因:[%s],retryId:[%s]", methodName, uid, context, e.getMessage(),
                    appPacket.getDbRetryId()));
        }
        return success;
    }

    private void sendGroup(AppPacket appPacket) {
        String methodName = "{xmpp.sendGroup}";
        logger.debug(String.format("%s开始推送:context:%s,gid:%s", methodName, appPacket.getContext(), appPacket.getRecvUserId()));

        String relativeGroupId = groupAppCache.loadByGroupId(appPacket.getAppChannelId(), appPacket.getRecvUserId());
        if (StringUtils.isBlank(relativeGroupId)) {
            Long gid = appPacket.getRecvUserId();
            List<Long> userIds = getUserIdsbyGid(gid);
            for (Long userId : userIds) {
                // send...
                appPacket.setRecvUserId(userId);
                appPacket.setDeviceToken(userId.toString());
                sendPoint(appPacket);
            }
        } else {
            // send group directly
            logger.error(String.format("%s调用群发失败.原因:%s.gid:%s,appchannelId:%s", methodName, "没有快捷群发接口", appPacket.getRecvUserId(),
                    appPacket.getAppChannelId()));
        }
    }

    @Override
    protected Tasks getTaskType() {
        return Tasks.FETCH_RETRY_XMPP;
    }

    @Override
    protected String getQueueName() {
        return "XMPP处理队列";
    }

    @Override
    protected Tasks getFullTaskType() {
        return Tasks.FETCH_RETRY_XMPP_FULL;
    }

    @Override
    protected String getFullQueueName() {
        return "全量XMPP处理队列";
    }

}
